package online.longzipeng.mywebdemo.utils;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author lzp
 * @Date:2023/3/8
 * @description: markdown 文件的一些处理
 */
@Slf4j
public class MarkdownFileUtils {

	/**
	 * 匹配markdown文件中图片的正则表达式 ，元组1中为图片描述，元组2中为图片地址 ![描述信息](图片的真实地址)
	 */
	private static final String regexImg = "!\\[(.*?)\\]\\((.*?)\\)";

	/**
	 * 移动本地markdown文件中的图片到指定目录
	 * 注意： 重名图片会直接覆盖！！
	 *
	 * @param mdPath       markdown 文件的路径
	 * @param targetImgDir 图片移动的目标文件夹
	 * @param onlyCopy     是否只是复制图片
	 */
	public static void moveImage(String mdPath, String targetImgDir, boolean onlyCopy) {
		/// 先全部路径替换为 /分割 保证路径统一
		String filePath = formatPath(mdPath);
		targetImgDir = formatPath(targetImgDir);

		// 通过设置的md文件路径取到相对路径 ,主要用于组装相对路径的图片真实路径
		/// 切割出相对路径
		String relativePath = filePath.substring(0, filePath.lastIndexOf("/") + 1);
		FileReader fileReader = new FileReader(filePath);
		// 从文件中读取内容为字符串
		String readString = fileReader.readString();
		// 最后覆盖输出的调整好的文件内容

		// 编译正则表达式
		Pattern patten = Pattern.compile(regexImg);
		// 指定要匹配的字符串
		Matcher matcher = patten.matcher(readString);
		List<String> matchImagePaths = new ArrayList<>();

		// 将匹配到的完整图片信息装入集合中， 此处find（）每次被调用后，会偏移到下一个匹配
		while (matcher.find()) {
			matchImagePaths.add(matcher.group());
		}
		// 获取当前目录下的所有md文件中的所有图片链接, 这里$2取的时正则中第二个元组内包含的数据
		Set<String> imagePaths = matchImagePaths.stream().map(v -> v.replaceAll(regexImg, "$2")).collect(Collectors.toSet());
		log.info("已提取出{}张图片，开始迁移图片", imagePaths.size());
		int moveCount = 0;
		for (String imgPath : imagePaths) {
			// 这里用一个新的变量来存真正的img地址，imgPath保留原值，用于后续替换地址
			String realImagePath = formatPath(imgPath);
			// 分别通过绝对路径和相对路径创建图片
			if (!FileUtil.exist(realImagePath)) {
				// 走绝对路径不存在，说明是相对路径,此时用文件的路径进行拼接
				realImagePath = relativePath + realImagePath;
			}
			if (FileUtil.exist(realImagePath)) {
				// 将图片复制到对应地址
				String targetImgPath = targetImgDir + realImagePath.substring(realImagePath.lastIndexOf("/"));
				log.info("原图片：{} 即将迁移到：{}", realImagePath, targetImgPath);

				// 待处理图片路径与原路径不一样时才处理
				if (!StrUtil.equals(imgPath, targetImgPath)) {
					// 复制或者移动图片
					if (onlyCopy) {
						FileUtil.copy(new File(realImagePath), new File(targetImgPath), true);
					} else {
						FileUtil.move(new File(realImagePath), new File(targetImgPath), true);
					}
					// 原文件中所有该 原路径图片地址，替换为目标图片路径
					readString = readString.replace(imgPath, targetImgPath);
					moveCount++;
				}
			}
		}
		// 文件写入
		FileWriter fileWriter = new FileWriter(filePath);
		fileWriter.write(readString);
		log.info("===========================");
		log.info("文件写入完毕！！");
		log.info("成功移动{}张图片", moveCount);
	}

	/**
	 * 格式化路径 ，将 \ 【反斜杠】 全部替换为 / 【正斜杠】
	 */
	public static String formatPath(String path) {
		return path.replaceAll("\\\\", "/");
	}

	public static void main(String[] args) {
		// 需要调整图片位置的md文件
		String filePath = "E:\\我的坚果云\\笔记\\java\\xxx.md";
		// 移动图片到目标目录
		String targetImgDir = "E:\\我的坚果云\\笔记\\java\\xxx\\imgs";

		moveImage(filePath, targetImgDir, true);

	}

}
